package net.ikenway.springboot.demo.Service.Implement;

import net.ikenway.springboot.demo.Dao.ProductRepository;
import net.ikenway.springboot.demo.Dao.ProductSortRepository;
import net.ikenway.springboot.demo.Model.Dto.ProductSortDto;
import net.ikenway.springboot.demo.Model.Entity.Product;
import net.ikenway.springboot.demo.Model.Entity.ProductSort;
import net.ikenway.springboot.demo.Service.Interface.ProductSortServiceIntf;
import net.ikenway.springboot.demo.Utils.MapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author MasterKenway <zk@ikenway.net>
 * @Description
 * @date Created Date 12/18/2020
 */
@Service
public class ProductSortServiceImpl implements ProductSortServiceIntf {

    private final ProductSortRepository productSortRepository;
    private final MapperUtil mapperUtil;
    private final ProductRepository productRepository;

    @Autowired
    ProductSortServiceImpl(ProductSortRepository productSortRepository, MapperUtil mapperUtil, ProductRepository productRepository) {
        this.productSortRepository = productSortRepository;
        this.mapperUtil = mapperUtil;
        this.productRepository = productRepository;
    }

    @Override
    public List<ProductSortDto> findAll() throws Exception {
        List<ProductSortDto> productSortDtos = new ArrayList<>();
        productSortRepository.findAll().iterator().forEachRemaining(productSort -> productSortDtos.add(mapperUtil.map(productSort, ProductSortDto.class)));
        return productSortDtos;
    }

    @Override
    public List<ProductSortDto> findAllByEnable(boolean enable) throws Exception {
        return mapperUtil.mapList(productSortRepository.findAllByEnableOrderByDisplayOrder(enable), ProductSortDto.class);
    }

    @Override
    public ProductSortDto create(ProductSortDto productSortDto) throws Exception {
        if (productSortRepository.findBySortName(productSortDto.getSortName()) != null) throw new EntityExistsException();
        if (productSortDto.getEnable() && productSortDto.getDisplayOrder() == null) throw new Exception("启用的分类显示顺序不能为空");
        if (!productSortDto.getEnable()) productSortDto.setDisplayOrder(null);
        return mapperUtil.map(productSortRepository.save(mapperUtil.map(productSortDto, ProductSort.class)), ProductSortDto.class);
    }

    @Override
    public void update(ProductSortDto productSortDto) throws Exception {
        existOrNot(productSortDto.getSortId());
        if (productSortDto.getEnable() && productSortDto.getDisplayOrder() == null) throw new Exception("启用的分类显示顺序不能为空");
        if (!productSortDto.getEnable()) productSortDto.setDisplayOrder(null);
        productSortRepository.save(mapperUtil.map(productSortDto, ProductSort.class));
    }

    @Transactional
    @Override
    public void delete(List<Long> sortIds) throws Exception {
        for (Long sortId: sortIds) {
            ProductSort productSort = existOrNot(sortId);
            List<Product> products = productRepository.findAllByProductSortSortId(productSort.getSortId());
            if (products != null && !products.isEmpty()) throw new Exception("存在与该分类相关联的商品 删除失败");
            productSortRepository.deleteById(sortId);
        }
    }

    @Override
    public ProductSort existOrNot(Long sortId) {
        return productSortRepository.findById(sortId).orElseThrow(EntityNotFoundException::new);
    }
}
